﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BaseAPI.BaseModel;
using BaseAPI.BaseViewModel;
using Microsoft.EntityFrameworkCore;

namespace BaseAPI.BaseController;

/// <summary>
/// 与数据库相关的Response层面的操作
/// </summary>
/// <typeparam name="T"></typeparam>
public class ControllerServer<T>(ModelServer<T> modelServer) : IDisposable
    where T : BaseEntity, new()
{
    #region 添加一个或多个

    /// <summary>
    /// 添加一个实体
    /// </summary>
    /// <param name="t"></param>
    /// <returns>成功或失败的响应（实体ID）</returns>
    public async Task<ResponseModel<string>> Add(T t)
    {
        try
        {
            await modelServer.Add(t);
        }
        catch (Exception e)
        {
            return ResponseModel<string>.HandleError(e);
        }

        return ResponseModel<string>.Success(t.ID.ToString());
    }

    /// <summary>
    /// 添加多个实体
    /// </summary>
    /// <param name="listT"></param>
    /// <returns>成功或失败的响应（实体ID列表）</returns>
    public async Task<ResponseModel<List<string>>> Add(List<T> listT)
    {
        try
        {
            var ids = await modelServer.Add(listT);
            return ResponseModel<List<string>>.Success(ids.Select(x => x.ToString()).ToList());
        }
        catch (Exception e)
        {
            return ResponseModel<List<string>>.HandleError(e);
        }
    }

    #endregion

    #region 删除一个或多个

    /// <summary>
    /// 删除一个实体
    /// </summary>
    /// <param name="id">实体ID</param>
    /// <returns>成功或失败的响应（null）</returns>
    public async Task<ResponseModel<int>> Remove(long id)
    {
        try
        {
            var count = await modelServer.Remove(id);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    /// <summary>
    /// 删除一个实体
    /// </summary>
    /// <param name="t">实体</param>
    /// <returns>成功或失败的响应（null）</returns>
    public async Task<ResponseModel<int>> Remove(T t)
    {
        try
        {
            var count = await modelServer.Remove(t);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    /// <summary>
    /// 删除多个实体
    /// </summary>
    /// <param name="listID">实体ID列表</param>
    /// <returns></returns>
    public async Task<ResponseModel<int>> Remove(List<long> listID)
    {
        try
        {
            var count = await modelServer.Remove(listID);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    /// <summary>
    /// 删除多个实体
    /// </summary>
    /// <param name="listT">实体列表</param>
    /// <returns>成功或失败的响应（null）</returns>
    public async Task<ResponseModel<int>> Remove(List<T> listT)
    {
        try
        {
            var count = await modelServer.Remove(listT);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    #endregion

    #region 修改一个或多个

    /// <summary>
    /// 更新实体（Put），如果传入patchFun则为部分更新（Patch）
    /// </summary>
    /// <param name="t">实体</param>
    /// <param name="patchFun">部分更新函数，返回true则执行部分更新</param>
    /// <returns>成功或失败的响应（null）</returns>
    public async Task<ResponseModel<int>> Modify(T t, Action<T, DbContext> patchFun = null)
    {
        try
        {
            var count = await modelServer.Modify(t, patchFun);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    /// <summary>
    /// 更新实体（Put），如果传入patchFun则为部分更新（Patch）
    /// </summary>
    /// <param name="patchModels">更新实体列表</param>
    /// <returns>成功或失败的响应（null）</returns>
    public async Task<ResponseModel<int>> Modify(List<PatchModel<T>> patchModels)
    {
        try
        {
            var count = await modelServer.Modify(patchModels);
            return ResponseModel<int>.Success(count);
        }
        catch (Exception e)
        {
            return ResponseModel<int>.HandleError(e);
        }
    }

    #endregion

    #region 查询

    /// <summary>
    /// 私有方法，返回分页后的实体列表
    /// </summary>
    /// <typeparam name="TU">返回的实体类型</typeparam>
    /// <param name="queryable">查询语句</param>
    /// <param name="pageRequest">分页信息</param>
    /// <returns>实体列表响应</returns>
    private async Task<ResponseModel<List<TU>>> GetPagedList<TU>(IQueryable<TU> queryable, PageRequest pageRequest)
    {
        try
        {
            if (pageRequest is { PageSize: > 0 })
            {
                //设置分页信息
                var rowCount = await queryable.CountAsync();
                var pageResponse = new PageResponse();
                pageResponse.SetPage(pageRequest.PageSize, rowCount);
                //获取分页实体
                var listT = await queryable.Skip((pageRequest.PageIndex - 1) * pageRequest.PageSize)
                    .Take(pageRequest.PageSize).ToListAsync();
                return ResponseModel<List<TU>>.Success(listT, pageResponse);
            }
            else
                return ResponseModel<List<TU>>.Success(await queryable.ToListAsync());
        }
        catch (Exception e)
        {
            return ResponseModel<List<TU>>.HandleError(e);
        }
    }

    /// <summary>
    /// 获取实体列表，一次初始查询
    /// </summary>
    /// <param name="pageRequest">分页信息</param>
    /// <returns>实体列表响应</returns>
    public async Task<ResponseModel<List<T>>> GetList(PageRequest pageRequest = null)
    {
        return await GetPagedList(modelServer.GetList(), pageRequest);
    }

    /// <summary>
    /// 获取实体列表，二次查询（查询发生在数据库查询之前）
    /// </summary>
    /// <param name="queryFun">IQueryable查询函数</param>
    /// <param name="pageRequest">分页信息</param>
    /// <returns>实体列表响应</returns>
    public async Task<ResponseModel<List<T>>> GetList(Func<IQueryable<T>, IQueryable<T>> queryFun,
        PageRequest pageRequest = null)
    {
        var queryable = queryFun(modelServer.GetList());
        return await GetPagedList(queryable, pageRequest);
    }

    /// <summary>
    /// 获取实体列表，二次查询（查询发生在数据库查询之前）
    /// </summary>
    /// <typeparam name="TU">返回的实体类型</typeparam>
    /// <param name="queryFun">IQueryable转换函数</param>
    /// <param name="pageRequest">分页信息</param>
    /// <returns>实体列表响应</returns>
    public async Task<ResponseModel<List<TU>>> GetList<TU>(Func<IQueryable<T>, IQueryable<TU>> queryFun,
        PageRequest pageRequest = null)
    {
        var queryable = queryFun(modelServer.GetList());
        return await GetPagedList(queryable, pageRequest);
    }

    /// <summary>
    /// 获取实体，一次初始查询
    /// </summary>
    /// <param name="id">实体ID</param>
    /// <returns>实体响应</returns>
    public async Task<ResponseModel<T>> GetOne(long id)
    {
        try
        {
            return ResponseModel<T>.Success(await modelServer.GetOne(id));
        }
        catch (Exception e)
        {
            return ResponseModel<T>.HandleError(e);
        }
    }

    /// <summary>
    /// 获取实体，二次查询（查询'查询函数'）
    /// </summary>
    /// <param name="queryFun">查询函数</param>
    /// <returns>实体响应</returns>
    public async Task<ResponseModel<T>> GetOne(Func<IQueryable<T>, IQueryable<T>> queryFun)
    {
        try
        {
            return ResponseModel<T>.Success(await modelServer.GetOne(queryFun));
        }
        catch (Exception e)
        {
            return ResponseModel<T>.HandleError(e);
        }
    }

    /// <summary>
    /// 获取实体，二次查询（查询ID和查询函数）
    /// </summary>
    /// <typeparam name="TU">返回类型</typeparam>
    /// <param name="id">实体ID</param>
    /// <param name="transFun">转换函数</param>
    /// <returns>实体响应</returns>
    public async Task<ResponseModel<TU>> GetOne<TU>(long id, Func<IQueryable<T>, IQueryable<TU>> transFun)
    {
        try
        {
            return ResponseModel<TU>.Success(await modelServer.GetOne(id, transFun));
        }
        catch (Exception e)
        {
            return ResponseModel<TU>.HandleError(e);
        }
    }

    /// <summary>
    /// 获取实体，二次查询（查询'查询函数'）
    /// </summary>
    /// <typeparam name="TU">返回类型</typeparam>
    /// <param name="transFun">转换函数</param>
    /// <returns>实体响应</returns>
    public async Task<ResponseModel<TU>> GetOne<TU>(Func<IQueryable<T>, IQueryable<TU>> transFun)
    {
        try
        {
            return ResponseModel<TU>.Success(await modelServer.GetOne(transFun));
        }
        catch (Exception e)
        {
            return ResponseModel<TU>.HandleError(e);
        }
    }

    #endregion

    public void Dispose()
    {
        modelServer.Dispose();
    }
}